package jmind.core.image;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.*;
import java.net.URL;
import java.util.Optional;

import javax.activation.URLDataSource;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;


import jmind.base.util.FileUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @author weibo-xie
 * 2012-8-14
 */

public class ImageUtil {
    private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    public static void main(String[] args) {

        // saveImage("http://photos.album.mop.com/c04/4b/4b/8c/dcc464/1236249958997.jpg","d:/input/sdf.jpg");
        Image img = getImage("d:/data/QQ20141218105636.jpg");
        ZoomImg(img, "d:/data/1.jpg", 300, 400);
        // cut("d:/data/engineering_28_1_0154d5af43783f8.jpg", "d:/data/1.jpg",
        // 50);
        // abscut("d:/data/engineering_28_1_0154d5af43783f8.jpg", 0, 99, 50, 50,
        // 50, 50);
        // ZoomImg(getImage("d:/data/engineering_28_1_0154d5af43783f8.jpg"),
        // "d:/data/z.jpg", 50, 50);

    }

    public static File write(BufferedImage image, String formartName, String imageFile) {
        File file = new File(imageFile);
        try {
            ImageIO.write(image, formartName, file);
        } catch (IOException e) {
            logger.error("", e);
        }
        return file;
    }

    /**
     * 图片到byte数组
     * https://www.cnblogs.com/Sharley/p/5591828.html
     *
     * @param path
     * @return
     */

    public static byte[] image2Byte(String path) {
        byte[] data = null;
        FileImageInputStream input = null;
        try {
            input = new FileImageInputStream(new File(path));
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
            output.close();

        } catch (Exception ex1) {
            logger.error("", ex1);
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                }
            }
        }
        return data;
    }

    //byte数组到图片
    public static void byte2Image(byte[] data, String path) {
        if (data.length < 3 || path.equals("")) {
            return;
        }
        FileImageOutputStream imageOutput = null;
        try {
            imageOutput = new FileImageOutputStream(new File(path));
            imageOutput.write(data, 0, data.length);
        } catch (Exception ex) {
            logger.error("", ex);
        } finally {
            if (imageOutput != null) {
                try {
                    imageOutput.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static String image2Base64(String imageFile) {
        try {
            BufferedImage bufferedimage = ImageIO.read(new File(imageFile));
            return image2Base64(bufferedimage,FileUtil.getExtensionName(imageFile));
        } catch (IOException e) {
            logger.error("", e);
            return null;
        }
    }

    public static String image2Base64(BufferedImage image, String formatName)  {
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, Optional.ofNullable(formatName).orElse("png"), bao);
            byte[] imagedata = bao.toByteArray();
            BASE64Encoder encoder = new BASE64Encoder();
            String base64image = encoder.encodeBuffer(imagedata).trim();
            base64image = base64image.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
            return base64image;
        }catch (Exception e){
            logger.error("",e);
        } finally {
            try {
                bao.close();
            } catch (IOException ex) {
            }
        }
         return null;

    }

    public static BufferedImage base642Image(String base64String) {
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes1 = decoder.decodeBuffer(base64String);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
            return ImageIO.read(bais);
        } catch (IOException e) {
            logger.error("", e);
            return null;
        }
    }

    /**
     * base64 转图片文件
     * @param base64String
     * @param filePath  文件名
     * @return
     */
    public static File base642Image(String base64String, String filePath) {
        try {
            BufferedImage image = base642Image(base64String);
            if(image!=null) {
                File file = new File(filePath);
                ImageIO.write(image, Optional.ofNullable(FileUtil.getExtensionName(filePath)).orElse("png"), file);
                return file;
            }
        } catch (IOException e) {
            logger.error("",e);
        }
          return null;
    }


    /**
     * 保存图片
     *
     * @param srcUrl   url
     * @param destFile 保存地址
     * @return
     */
    public static File save(String srcUrl, String destFile) {
        try {
            File f = new File(destFile);
            File parent = f.getParentFile();
            if (!parent.exists()) {
                parent.mkdirs();
            }
            URL url = new URL(srcUrl);
            URLDataSource uds = new URLDataSource(url);
            InputStream is = uds.getInputStream();
            FileOutputStream fos = new FileOutputStream(f);
            byte[] buff = new byte[1024 * 8];
            int read = 0;
            while ((read = is.read(buff)) > 0) {
                fos.write(buff, 0, read);
            }
            fos.close();
            is.close();

            return f;
        } catch (Exception ex) {
            logger.error("", ex);
            return null;
        }
    }


    /**
     * 缩放
     *
     * @param src       原图
     * @param targetImg 新图
     * @param widths
     * @param heights
     */

    public static void ZoomImg(Image src, String targetImg, double widths, double heights) {
        try {
            // File _file = new File(img);
            // Image src = ImageIO.read(_file);
            double a = widths / src.getWidth(null);
            double b = heights / src.getHeight(null);
            if (a > b) {
                a = b;
            }
            int width = (int) (src.getWidth(null) * a); // 681
            int height = (int) (src.getHeight(null) * a); // 511
            if (a > 1) {
                width = src.getWidth(null); // 681
                height = src.getHeight(null); // 511
                return;
            }
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);

            g.dispose();
            //            FileOutputStream out = new FileOutputStream(targetImg);
            //            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //            encoder.encode(image);
            //            out.close();

            ImageIO.write(image, FileUtil.getExtensionName(targetImg), new File(targetImg));
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    /**
     * 裁剪
     *
     * @param img       原图
     * @param targetImg 新图
     * @param width
     */
    public static void cut(String img, String targetImg, int width) {
        try {
            File _file = new File(img);
            Image src = ImageIO.read(_file);
            int sourceWidth = src.getWidth(null);
            int sourceHeight = src.getHeight(null);
            int x = 0;
            int y = 0;
            if (sourceWidth > sourceHeight) {// 宽大于高
                x = (sourceWidth - sourceHeight) / 2;
            } else {
                y = (sourceHeight - sourceWidth) / 2;
            }
            BufferedImage image = new BufferedImage(width, width, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, x, y, width, width, null);
            g.dispose();
            //            FileOutputStream out = new FileOutputStream(targetImg);
            //            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //            encoder.encode(image);
            //            out.close();
            ImageIO.write(image, FileUtil.getExtensionName(targetImg), new File(targetImg));
        } catch (Exception e) {
            logger.error("", e);
        }

    }

    public static Image getImage(String img) {
        File _file = new File(img);
        try {
            Image src = ImageIO.read(_file);
            return src;
        } catch (IOException e) {
            logger.error("", e);
            return null;
        }
    }

    /**
     * 把图片印刷到图片上
     *
     * @param pressImg  -- 水印文件
     * @param targetImg -- 目标文件
     * @param x         --x坐标
     * @param y         --y坐标
     */

    public static void pressImage(String pressImg, String targetImg, int x, int y) {
        try {
            // 目标文件
            File _file = new File(targetImg);
            Image src = ImageIO.read(_file);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            if (width < 300 && height < 300) {
                System.out.println("small");
                return;
            }

            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);
            // 水印文件
            File _filebiao = new File(pressImg);
            Image src_biao = ImageIO.read(_filebiao);
            int wideth_biao = src_biao.getWidth(null);
            int height_biao = src_biao.getHeight(null);

            g.drawImage(src_biao, x, y, wideth_biao, height_biao, null);
            // g.drawImage(src_biao, x, y, 155, 344,0, 0, wideth_biao,
            // height_biao, null);
            // 水印文件结束
            g.dispose();
            //            FileOutputStream out = new FileOutputStream(targetImg);
            //            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //            encoder.encode(image);
            //            out.close();
            ImageIO.write(image, FileUtil.getExtensionName(targetImg), new File(targetImg));
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    /**
     * @param pressImg  水印文件
     * @param targetImg 目标文件
     */
    public static void pressImage(String pressImg, String targetImg) {
        try {
            // 目标文件
            File _file = new File(targetImg);
            Image src = ImageIO.read(_file);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            if (width < 300 && height < 300) {
                System.out.println("small");
                return;
            }

            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);
            // 水印文件
            File _filebiao = new File(pressImg);
            Image src_biao = ImageIO.read(_filebiao);
            int wideth_biao = src_biao.getWidth(null);
            int height_biao = src_biao.getHeight(null);
            // 图片出现的位置
            int x = width - wideth_biao - 10;
            int y = height - height_biao - 10; // (height - height_biao) / 2 ;
            g.drawImage(src_biao, x, y, wideth_biao, height_biao, null);
            // 水印文件结束
            g.dispose();
            //            FileOutputStream out = new FileOutputStream(targetImg);
            //            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //            encoder.encode(image);
            //            out.close();
            ImageIO.write(image, FileUtil.getExtensionName(targetImg), new File(targetImg));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** */
    /**
     * 打印文字水印图片
     *
     * @param pressText --文字
     * @param targetImg -- 目标图片
     * @param fontName  -- 字体名
     * @param fontStyle -- 字体样式
     * @param color     -- 字体颜色
     * @param fontSize  -- 字体大小
     * @param x         -- 偏移量
     * @param y
     */
    public static void pressText(String pressText, String targetImg, String fontName, int fontStyle, Color color,
                                 int fontSize, int x, int y) {
        try {
            File _file = new File(targetImg);
            Image src = ImageIO.read(_file);
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(src, 0, 0, width, height, null);
            // String s="www.qhd.com.cn";
            g.setColor(color);
            g.setFont(new Font(fontName, fontStyle, fontSize));
            // g.drawString(pressText, width - fontSize - x, height - fontSize /
            // 2- y);
            g.drawString(pressText, x, y);
            g.dispose();
            //            FileOutputStream out = new FileOutputStream(targetImg);
            //            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            //            encoder.encode(image);
            //           out.close();
            ImageIO.write(image, FileUtil.getExtensionName(targetImg), new File(targetImg));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getType(String srcFileName) {
        return getType(new File(srcFileName));
    }

    public static String getType(File file) {
        FileInputStream imgFile = null;
        byte[] b = new byte[10];
        int l = -1;
        try {
            imgFile = new FileInputStream(file);
            l = imgFile.read(b);
            imgFile.close();
        } catch (Exception e) {
            return null;
        }

        if (l == 10) {
            byte b0 = b[0];
            byte b1 = b[1];
            byte b2 = b[2];
            byte b3 = b[3];
            byte b6 = b[6];
            byte b7 = b[7];
            byte b8 = b[8];
            byte b9 = b[9];
            if (b0 == (byte) 'G' && b1 == (byte) 'I' && b2 == (byte) 'F') {
                return "gif";
            } else if (b0 == (byte) 'B' && b1 == (byte) 'M') {
                return "bmp";
            } else if (b1 == (byte) 'P' && b2 == (byte) 'N' && b3 == (byte) 'G') {
                return "png";
            } else if (b6 == (byte) 'J' && b7 == (byte) 'F' && b8 == (byte) 'I' && b9 == (byte) 'F') {
                return "jpg";
            } else if (b6 == (byte) 'E' && b7 == (byte) 'x' && b8 == (byte) 'i' && b9 == (byte) 'f') {
                return "jpg";
            }
        }
        return null;
    }

    public static void abscut(String srcImageFile, int x, int y, int destWidth, int destHeight, int finalWidth,
                              int finalHeight) {
        try {
            Image img;
            ImageFilter cropFilter;
            // 读取源图像
            BufferedImage bi = ImageIO.read(new File(srcImageFile));
            int srcWidth = bi.getWidth(); // 源图宽度
            int srcHeight = bi.getHeight(); // 源图高度

            System.out.println("srcWidth= " + srcWidth + "\tsrcHeight= " + srcHeight);
            if (srcWidth >= destWidth && srcHeight >= destHeight) {
                Image image = bi.getScaledInstance(finalWidth, finalHeight, Image.SCALE_DEFAULT);// 获取缩放后的图片大小
                cropFilter = new CropImageFilter(x, y, destWidth, destHeight);
                img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
                BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                g.drawImage(img, 0, 0, null); // 绘制截取后的图
                g.dispose();
                // 输出为文件
                ImageIO.write(tag, "JPEG", new File(srcImageFile));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
